package cn.ad.service;

import cn.ad.common.Constant;
import cn.ad.common.DataUtils;
import cn.ad.enumration.*;
import cn.ad.exception.CreativeGroupValidateException;
import cn.ad.exception.CreativeValidateException;
import cn.ad.handler.SqlSessionHandler;
import cn.ad.interceptor.PageParameter;
import cn.ad.model.*;
import cn.ad.entity.*;
import com.alibaba.druid.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * 创意服务层实现
 *
 * @author yujuan.zhang
 * @from 2016-06-14
 * @since V1.0
 *
 */
@Service
public class CreativeService {

	private static Logger logger = LoggerFactory.getLogger(CreativeService.class);

	@Autowired
	private SqlSessionHandler sqlSessionHandler;

	@Autowired
	private CreativeGroupService creativeGroupService;

	@Autowired
	private AdMaterialService adMaterialService;

	@Autowired
	private AdMaterialAuditService adMaterialAuditService;

	@Autowired
	private PlatformService platformService;

	@Autowired
	private AdTemplateService adTemplateService;

	@Autowired
	private AdSizeService adSizeService;

	@Autowired
	private CampaignService campaignService;

	@Autowired
	private CreativeFormatMaterialSpecService creativeFormatMaterialSpecService;

	@Autowired
	private AdTemplateSpecService adTemplateSpecService;

	@Autowired
	private PlatformFormatSizeMapService platformFormatSizeMapService;
	
	/**
	 * 查询订单下的创意列表信息
	 */
	public ResultSetList<CreativeListModel> findCreatives(Map<String, Object> searchMap, PageParameter pageInfo) {

		// 获取到创意列表
		List<CreativeListModel> creativeList = sqlSessionHandler.selectList("creativeMapper.creative:list:page", searchMap, pageInfo);

		// 封装成BO对象
		return new ResultSetList<>(pageInfo.getTotalCount(), creativeList);

	}

	/**
	 * 查询出策略关联的创意列表
	 */
	public List<CreativeModel> findCreateivesByStrategyId(Integer id) {

		return sqlSessionHandler.selectList("creativeMapper.selectCreativesByStrategyId", id);
	}

	public List<CreativeModel> findCreateivesByCreateiveGroupId(Integer campaignId, int creativeGroupId) {

		Map<String,Object> params = new HashMap<>();
		params.put("campaignId", campaignId);
		params.put("creativeGroupId", creativeGroupId);
		return sqlSessionHandler.selectList("creativeMapper.select:creative:list:with:creativeGroup", params);
	}

	/**
	 * 查询创意分页列表，using for Strategy
	 */
	public ResultSetList<CreativeModel> findCreativesForStrategy(Map<String, Object> searchMap, PageParameter pageInfo) {
		// 获取到创意列表
		List<CreativeModel> creativeList = sqlSessionHandler.selectList("creativeMapper.creative:for:strategy:list:page", searchMap, pageInfo);

		// 封装成BO对象
		return new ResultSetList<CreativeModel>(pageInfo.getTotalCount(), creativeList);


	}

	public ResultSetList<CreativeModel> findCreativesPlatformForStrategy(Map<String, Object> searchMap, PageParameter pageInfo) {
		// 获取到创意列表
		List<CreativeModel> creativeList = sqlSessionHandler.selectList("creativeMapper.creative:for:strategy:by:platform:list:page", searchMap, pageInfo);
		// 封装成BO对象
		return new ResultSetList<CreativeModel>(pageInfo.getTotalCount(), creativeList);
	}

	public ResultSetList<CreativeModel> findCreativesForCreateiveGroup(Map<String, Object> searchMap, PageParameter pageInfo) {
		// 获取到创意列表
		List<CreativeModel> creativeList = sqlSessionHandler.selectList("creativeMapper.creative:creativeGroup:for:strategy:list:page", searchMap, pageInfo);

		// 封装成BO对象
		return new ResultSetList<CreativeModel>(pageInfo.getTotalCount(), creativeList);
	}

	/**
	 * 查询创意详细信息
	 */
	public CreativeDetailModel getCreativeById(Integer id) {

		// 查询创意信息
		CreativeDetailModel creativeDetailModel = sqlSessionHandler.selectOne("creativeMapper.selectById", id);

		// 根据创意形式查询该创意下的所有素材
		selectMaterialList(creativeDetailModel);

		return creativeDetailModel;
	}

	/**
	 * 验证创意在订单下名称是否存在重复
	 *
	 * @param creativeDetailModel
	 * @return
	 */
	private boolean hasCreative(CreativeDetailModel creativeDetailModel) {

		return (int)sqlSessionHandler.selectOne("creativeMapper.creative:checkname", creativeDetailModel) > 0;
	}

	public List<Creative> selectCreativeList(int campaignId) {

		return sqlSessionHandler.selectList("creativeMapper.select:creative:list", campaignId);
	}

	public CreativeDefaultModel getCreativeDefaultByAdId(int adId) {
		return sqlSessionHandler.selectOne("creativeMapper.selectDefaultByAdId",adId);
	}

	public List<CreativeDefaultModel> getCreativeListByFomartId(Integer formatId, Integer templateId) {
		List<CreativeDefaultModel> creativeList= null;
		if(formatId==AdFormat.ADFORMAT_NATIVE.getValue()){
			if(templateId==null){
				return new ArrayList<>();
			}
			creativeList=sqlSessionHandler.selectList("creativeMapper.selectList:creative:native",templateId);
		}else{
			creativeList=sqlSessionHandler.selectList("creativeMapper.selectList:creative:unNative",formatId);
		}
		return creativeList;
	}


	/**
	 * 新建创意
	 */
	@Transactional
	public void addCreative(CreativeDetailModel creativeDetailModel) {
		// 创意名称重复验证
		if (hasCreative(creativeDetailModel)) {
			throw new CreativeValidateException(CreativeValidateException.ErrorCode.CREATIVE_REPEAT);
		}

		// 参数验证
		creativeParamValidate(creativeDetailModel);

		// 设置创意交互信息
		addCreativeInteraction(creativeDetailModel);

		// 写入creative表, 并返回创意ID
		sqlSessionHandler.insert("creativeMapper.insert", creativeDetailModel);

		// 如果该创意属于某个创意分组 add from DSP V2 2016-08-31
		if (creativeDetailModel.getCreativeGroupId() != null) {
			// 验证订单下是否存在该创意分组
			CreativeGroup creativeGroup = creativeGroupService.selectCreativeGroupById(creativeDetailModel.getCreativeGroupId());
			if (creativeGroup == null || creativeGroup.getCampaignId() == null || !creativeGroup.getCampaignId().equals(creativeDetailModel.getCampaignId())) {
				throw new CreativeValidateException(CreativeValidateException.ErrorCode.CREATIVE_CREATIVEGROUP_NOTFOUND);
			}

			// 写入创意分组和创意map关系表
			CreativeGroupCreativeMap creativeGroupCreativeMap = new CreativeGroupCreativeMap();
			creativeGroupCreativeMap.setCreativeGroupId(creativeDetailModel.getCreativeGroupId());
			creativeGroupCreativeMap.setCreativeId(creativeDetailModel.getId());
			sqlSessionHandler.insert("creativeGroupCreativeMapMapper.insert", creativeGroupCreativeMap);
		}

		// 如果该创意有素材，写入ad_material表
		if (!CollectionUtils.isEmpty(creativeDetailModel.getMaterials())) {

			for (AdMaterialDetailModel adMaterialDetailModel : creativeDetailModel.getMaterials()) {
				// 写入素材表
				addOrUpdateAdMaterialInfo(creativeDetailModel, adMaterialDetailModel);

				// 原生创意形式需要写入ad_material_group表
				if (creativeDetailModel.getAdFormat() == AdFormat.ADFORMAT_NATIVE.getValue()) {
					addAdMaterialGroup(creativeDetailModel, adMaterialDetailModel);
				}

			}

			// 原生创意时, 写入素材审核表 ad_material_audit
			if (creativeDetailModel.getAdFormat() == AdFormat.ADFORMAT_NATIVE.getValue()) {
				addAdMaterialAuditInfoForNativeCreative(creativeDetailModel);
			}
		}
	}

	// 原生创意形式时， 写入素材审核表
	private void addAdMaterialAuditInfoForNativeCreative(CreativeDetailModel creativeDetailModel) {
		AdMaterialAudit adMaterialAudit = new AdMaterialAudit();
		adMaterialAudit.setAdFormatId(creativeDetailModel.getAdFormat());
		adMaterialAudit.setAuditId(new StringBuilder("c").append(creativeDetailModel.getId()).toString());
		adMaterialAudit.setCreativeId(creativeDetailModel.getId());
		// 待审核状态
		adMaterialAudit.setAuditStatus(AuditStatus.PENDING.getValue());
		// 模版所属的平台ID
		adMaterialAudit.setPlatformId(creativeDetailModel.getPlatformId());
		// 写入素材审核表
		sqlSessionHandler.insert("adMaterialAuditMapper.insert", adMaterialAudit);
	}


	// 原生广告需要写入素材组表
	private void addAdMaterialGroup(CreativeDetailModel creativeDetailModel, AdMaterialDetailModel adMaterialDetailModel) {
		// 当为原生广告形式时，需要写入ad_material_group表
		AdMaterialGroup adMaterialGroup = new AdMaterialGroup();
		// 设置对应的创意ID
		adMaterialGroup.setCreativeId(creativeDetailModel.getId());
		// 设置对应的模版ID
		adMaterialGroup.setTemplateId(creativeDetailModel.getTemplateId());
		// 设置对应的(元素)素材ID
		adMaterialGroup.setMaterialId(adMaterialDetailModel.getId());
		// 设置原生模版素材规格ID
		adMaterialGroup.setTemplateSpecId(adMaterialDetailModel.getTemplateSpecId());
		sqlSessionHandler.insert("adMaterialGroupMapper.insert", adMaterialGroup);
	}

	// 添加素材
	private void addOrUpdateAdMaterialInfo(CreativeDetailModel creativeDetailModel, AdMaterialDetailModel adMaterialDetailModel) {
		// 设置素材对应的创意ID
		adMaterialDetailModel.setCreativeId(creativeDetailModel.getId());

		// FIXME 非原生创意形式时，素材类型只有图片，没有传material_type_id，后台需要设置
		if (creativeDetailModel.getAdFormat() != AdFormat.ADFORMAT_NATIVE.getValue()) {
			adMaterialDetailModel.setMaterialTypeId(MaterialType.MATERIALTYPE_PICTURE.getValue());
		} else {
			// 原生创意形式时，如果为图片元素，需要设置尺寸id
			if (adMaterialDetailModel.getMaterialTypeId() == MaterialType.MATERIALTYPE_PICTURE.getValue()) {
				// 模版元素规格id查询图片元素对应的尺寸id
				AdTemplateSpec adTemplateSpec = sqlSessionHandler.selectOne("adTemplateSpecMapper.selectById", adMaterialDetailModel.getTemplateSpecId());
				adMaterialDetailModel.setSizeId(adTemplateSpec == null ? null : adTemplateSpec.getAdSizeId());
			}
		}

		// 根据图片url后缀 判断图片格式 jpg 或者 png 等等
		// FIXME 如果有传material_type_id 可以根据这个值取判断是否是文字
		if (adMaterialDetailModel.getMaterialTypeId() == MaterialType.MATERIALTYPE_PICTURE.getValue()
				&& !StringUtils.isEmpty(adMaterialDetailModel.getMaterialUrl())) {
			String materialUrl = adMaterialDetailModel.getMaterialUrl();
			String materialFormatSuffix = materialUrl.substring(materialUrl.lastIndexOf(".") + 1);
			// TODO 暂时jpeg和jpg使用同一个枚举值
			if ("jpeg".equalsIgnoreCase(materialFormatSuffix)) {
				adMaterialDetailModel.setMaterialFormat(MaterialFormat.MATERIALFORMAT_JPG.getValue());
			} else {
				adMaterialDetailModel.setMaterialFormat(MaterialFormat.forValue(materialFormatSuffix));
			}
		}

		if (adMaterialDetailModel.getMaterialTypeId() == MaterialType.MATERIALTYPE_TEXT.getValue()) {
			adMaterialDetailModel.setMaterialFormat(MaterialFormat.MATERIALFORMAT_TEXT.getValue());
		}

		if (adMaterialDetailModel.getId() == 0) {
			// 写入ad_material表, 并返回素材ID
			sqlSessionHandler.insert("adMaterialMapper.insert", adMaterialDetailModel);
		} else {
			// 更新素材表
			adMaterialDetailModel.setStatus(1);
			sqlSessionHandler.update("adMaterialMapper.update", adMaterialDetailModel);
		}
	}

	// 设置创意的交互信息
	private void addCreativeInteraction(CreativeDetailModel creativeDetailModel) {
		// Link跳转
		if (creativeDetailModel.getInteractionType() == InteractionType.INTERACTIONTYPE_REDIRECT.getValue()) {
			InteractionRedirects interactionRedirects = new InteractionRedirects();
			interactionRedirects.setTargetUrl(creativeDetailModel.getTargetUrl());
			// 写入 interaction_redirects表, 并返回Id
			sqlSessionHandler.insert("interactionRedirectsMapper.insert", interactionRedirects);
			creativeDetailModel.setInteractionId(interactionRedirects.getId());
		}

		// APP下载
		if (creativeDetailModel.getInteractionType() == InteractionType.INTERACTIONTYPE_APP.getValue()) {
			InteractionApp interactionApp = new InteractionApp();
			interactionApp.setName(creativeDetailModel.getAppName());
			interactionApp.setStoreId(creativeDetailModel.getStoreId());
			interactionApp.setAppType(creativeDetailModel.getAppType());
			interactionApp.setDownloadUrl(creativeDetailModel.getDownloadUrl());
			interactionApp.setClassesId(creativeDetailModel.getClassesId());
			// 写入数据库时 app大小 MB -> KB
			interactionApp.setAppVolume(null == creativeDetailModel.getAppVolume() ? null : (new Float(creativeDetailModel.getAppVolume() * 1000)));
			interactionApp.setApkName(creativeDetailModel.getApkName());

			// 设置应用介绍
			interactionApp.setDescription(creativeDetailModel.getAppDesc());

			// 写入 interaction_app表, 并返回Id
			sqlSessionHandler.insert("interactionAppMapper.insert", interactionApp);
			creativeDetailModel.setInteractionId(interactionApp.getId());
		}
	}

	// 更新创意表
	private void updateCreativeInfo(CreativeDetailModel creativeDetailModel, CreativeDetailModel creativeDetailInfoFromDB) {
		// 如果创意名称有修改，需要验证创意名称是否重复
		if (!StringUtils.equals(creativeDetailModel.getName(), creativeDetailInfoFromDB.getName())) {
			if (hasCreative(creativeDetailModel)) {
				throw new CreativeValidateException(CreativeValidateException.ErrorCode.CREATIVE_REPEAT);
			}
		}

		// 更新创意表
		sqlSessionHandler.update("creativeMapper.update", creativeDetailModel);
	}

	// 原生创意时， 更新原生模版元素列表
	private void updateAdMaterialListForNativeCreative(CreativeDetailModel creativeDetailModel,
                                                       boolean creativeInfoChangeFlag, List<AdMaterialDetailModel> materialsFromDB,
                                                       List<AdMaterialDetailModel> materialsFromParam, boolean materialInfoChangeFlag, Integer channelId) {

		// 如果模版元素有修改，需要更新模版元素
		if (materialInfoChangeFlag) {
			for (AdMaterialDetailModel materialFromParam : materialsFromParam) {
				// 更新元素列表
				for (AdMaterialDetailModel materialFromDB : materialsFromDB) {
					if (materialFromParam.getId() == materialFromDB.getId()) {
						// 如果为图片元素
						if (materialFromParam.getMaterialTypeId() == MaterialType.MATERIALTYPE_PICTURE.getValue()) {
							// 图片元素有修改
							if (!StringUtils.equals(materialFromParam.getMaterialUrl(),	materialFromDB.getMaterialUrl())) {
								// 设置图片元素的格式
								String materialUrl = materialFromParam.getMaterialUrl();
								String materialFormatSuffix = materialUrl.substring(materialUrl.lastIndexOf(".") + 1);
								// TODO 暂时jpeg和jpg使用同一个枚举值
								if ("jpeg".equalsIgnoreCase(materialFormatSuffix)) {
									materialFromParam.setMaterialFormat(MaterialFormat.MATERIALFORMAT_JPG.getValue());
								} else {
									materialFromParam.setMaterialFormat(MaterialFormat.forValue(materialFormatSuffix));
								}

								// 模版元素规格id查询图片元素对应的尺寸id
								AdTemplateSpec adTemplateSpec = sqlSessionHandler.selectOne("adTemplateSpecMapper.selectById", materialFromParam.getTemplateSpecId());
								materialFromParam.setSizeId(adTemplateSpec == null ? null : adTemplateSpec.getAdSizeId());

								// 更新图片元素
								sqlSessionHandler.update("adMaterialMapper.update", materialFromParam);
							}
						}

						// 如果为文本元素
						if (materialFromParam.getMaterialTypeId() == MaterialType.MATERIALTYPE_TEXT.getValue()) {
							// 文本元素有修改
							if (!StringUtils.equals(materialFromParam.getMaterialText(), materialFromDB.getMaterialText())) {
								// 设置素材格式
								materialFromParam.setMaterialFormat(MaterialFormat.MATERIALFORMAT_TEXT.getValue());
								// 更新文本元素
								sqlSessionHandler.update("adMaterialMapper.update", materialFromParam);
							}
						}
					}
				}
			}
		}

	}

	// 判断原生模版元素是否有修改(原生创意时不能修改平台和模版，理论上不会存在元素的新增和删除)
	private boolean isAdTemplateElementInfoChangeForNativeCreative(List<AdMaterialDetailModel> materialsFromDB, List<AdMaterialDetailModel> materialsFromParam) {
		// 设置flag标识模版元素是否有修改
		boolean materialInfoChangeFlag = false;

		// (原生创意时不能修改平台和模版，理论上不会存在元素的新增和删除)
		for (AdMaterialDetailModel materialFromParam : materialsFromParam) {

			// 判断原生模版元素是否有修改
			for (AdMaterialDetailModel materialFromDB : materialsFromDB) {
				if (materialFromParam.getId() == materialFromDB.getId()) {
					// 如果是图片元素，判断图片是否有修改
					if (materialFromParam.getMaterialTypeId() == MaterialType.MATERIALTYPE_PICTURE.getValue()) {
						if (!StringUtils.equals(materialFromParam.getMaterialUrl(), materialFromDB.getMaterialUrl())) {
							materialInfoChangeFlag = true;
							break;
						}
					}
					// 如果是文本元素，判断文本是否有修改
					if (materialFromParam.getMaterialTypeId() == MaterialType.MATERIALTYPE_TEXT.getValue()) {
						if (!StringUtils.equals(materialFromParam.getMaterialText(), materialFromDB.getMaterialText())){
							materialInfoChangeFlag = true;
							break;
						}
					}
				}

				// 只要有一个元素有修改就终止for循环
				if (materialInfoChangeFlag) {
					break;
				}
			}
		}
		return materialInfoChangeFlag;
	}

	// 更新创意的交互信息
	private void updateInteractionInfoWhenEditCreative(CreativeDetailModel creativeDetailModel, CreativeDetailModel creativeDetailInfoFromDB) {
		// 更新创意的交互信息
		if (creativeDetailModel.getInteractionType() == creativeDetailInfoFromDB.getInteractionType()) {// 创意的交互方式不变
			if (creativeDetailModel.getInteractionType() == InteractionType.INTERACTIONTYPE_REDIRECT.getValue()) {
				if (!StringUtils.equals(creativeDetailModel.getTargetUrl(), creativeDetailInfoFromDB.getTargetUrl())) {
					InteractionRedirects redirect = new InteractionRedirects();
					redirect.setId(creativeDetailInfoFromDB.getInteractionId());
					redirect.setTargetUrl(creativeDetailModel.getTargetUrl());
					sqlSessionHandler.update("interactionRedirectsMapper.update", redirect);
				}
			}

			if (creativeDetailModel.getInteractionType() == InteractionType.INTERACTIONTYPE_APP.getValue()) {
				InteractionApp app = new InteractionApp();
				app.setId(creativeDetailInfoFromDB.getInteractionId());
				app.setApkName(creativeDetailModel.getApkName());
				app.setAppType(creativeDetailModel.getAppType());
				// 写入数据库时 app大小 MB -> KB
				app.setAppVolume(null == creativeDetailModel.getAppVolume() ? null : (new Float(creativeDetailModel.getAppVolume() * 1000)));
				app.setName(creativeDetailModel.getAppName());
				app.setClassesId(creativeDetailModel.getClassesId());
				app.setDownloadUrl(creativeDetailModel.getDownloadUrl());
				app.setStoreId(creativeDetailModel.getStoreId());
				// 设置应用介绍
				app.setDescription(creativeDetailModel.getAppDesc());
				sqlSessionHandler.update("interactionAppMapper.update", app);
			}
		} else {// 创意的交互方式有修改
			addCreativeInteraction(creativeDetailModel);
		}
	}

	/**
	 * 查询订单下的创意列表， 用于素材审核列表查询
	 */
	public ResultSetList<Creative> getCreativeListForMaterialAuditList(Map<String, Object> searchMap, PageParameter pageInfo) {
		List<Creative> creativeList = sqlSessionHandler.selectList("creativeMapper.creative:for:select:materialAudit:list:page", searchMap, pageInfo);
		return new ResultSetList<>(pageInfo.getTotalCount(), creativeList);
	}

	/**
	 * 根据创意ID获取素材审核列表
	 */
	public List<AdMaterialAuditGeneralInfoModel> getAdMaterialAuditList(Integer creativeId) {
		Map<String, Object> mapParam = new HashMap<>();
		mapParam.put("creativeId", creativeId);
		mapParam.put("materialId", null);
		return sqlSessionHandler.selectList("adMaterialAuditMapper.select:material:audit:general:info", mapParam);
	}

	/**
	 * 更新素材审核状态
	 */
	public void updateMaterialAuditStatus(Integer creativeId, Integer materialId, Integer platformId, Integer auditStatus) {
		Map<String, Object> mapParam = new HashMap<>();
		mapParam.put("creativeId", creativeId);
		mapParam.put("materialId", materialId);
		mapParam.put("platformId", platformId);
		mapParam.put("auditStatus", auditStatus);
		sqlSessionHandler.update("adMaterialAuditMapper.update:material:audit:status", mapParam);
	}

	/**
	 * 查询某一个素材的审核概况信息
	 */
	public AdMaterialAuditGeneralInfoModel getAdMaterialAuditGeneralInfo(Integer creativeId, Integer materialId) {
		Map<String, Object> mapParam = new HashMap<>();
		mapParam.put("creativeId", creativeId);
		mapParam.put("materialId", materialId);
		return sqlSessionHandler.selectOne("adMaterialAuditMapper.select:material:audit:general:info", mapParam);
	}


	/**
	 * 查询创意详细信息 from DSP V2
	 */
	public CreativeDetailModel selectCreativeById(Integer cid, Integer id) {
		Map<String, Object> creativeParams = new HashMap<String, Object>();
		creativeParams.put("campaignId", cid);
		creativeParams.put("id", id);

		// 查询创意或者素材的交互信息
		CreativeDetailModel creativeDetailModel = sqlSessionHandler.selectOne("creativeMapper.creative:selectById", creativeParams);

		// 根据创意形式查询该创意下的所有素材
		selectMaterialList(creativeDetailModel);

		return creativeDetailModel;
	}

	/***
	 * 编辑创意  Modify from DSP V2
	 */
	@Transactional
	public void editCreativeV2(CreativeDetailModel creativeDetailModel) {
		// 参数验证
		creativeParamValidate(creativeDetailModel);

		// 从数据库查询出创意
		CreativeDetailModel creativeDetailInfoFromDB = selectCreativeById(creativeDetailModel.getCampaignId(), creativeDetailModel.getId());

		validateCreativeInfoChangeWhenEditCreative(creativeDetailModel, creativeDetailInfoFromDB);

		// 更新创意的交互信息
		updateInteractionInfoWhenEditCreative(creativeDetailModel, creativeDetailInfoFromDB);

		// 更新创意表
		updateCreativeInfo(creativeDetailModel, creativeDetailInfoFromDB);

		// 从数据库查询出的素材列表
		List<AdMaterialDetailModel> materialsFromDB = creativeDetailInfoFromDB.getMaterials();
		// 前端传递过来的素材列表
		List<AdMaterialDetailModel> materialsFromParam = creativeDetailModel.getMaterials();

		// 更新素材以及审核信息
		if (creativeDetailInfoFromDB.getAdFormat() == AdFormat.ADFORMAT_NATIVE.getValue()) {
			// 设置flag标识创意是否有修改
			// 查询该平台对应的channel ID
			int channelId = sqlSessionHandler.selectOne("platformMapper.select:channel", creativeDetailModel.getPlatformId());
			// 根据channel ID 来判断创意的修改点
			boolean creativeInfoChangeFlag = isCreativeInfoChangeForChannel(channelId, creativeDetailModel, creativeDetailInfoFromDB);

			// 设置flag标识素材是否有修改
			boolean materialInfoChangeFlag = isAdTemplateElementInfoChangeForNativeCreative(materialsFromDB, materialsFromParam);

			// 更新模版元素以及审核信息
			updateAdMaterialListForNativeCreative(creativeDetailModel, creativeInfoChangeFlag, materialsFromDB, materialsFromParam, materialInfoChangeFlag, channelId);
		}
	}


	// 更新创意(素材)审核状态
	private void updateMaterialAuditStatus(Integer creativeId, Integer materialId, Integer platformId, String auditId, Integer auditStatus) {
		Map<String, Object> mapParams = new HashMap<>();
		mapParams.put("creativeId", creativeId);
		mapParams.put("materialId", materialId);
		mapParams.put("platformId", platformId);
		mapParams.put("auditId", auditId);
		mapParams.put("auditStatus", auditStatus);
		sqlSessionHandler.update("adMaterialAuditMapper.update:material:audit:status", mapParams);
	}

	/**
	 * 更新创意状态
	 */
	@Transactional
	public void updateLocalCreativeStatus(Integer cid, Integer id, Integer status) {
		Map<String, Object> mapParams = new HashMap<>();
		mapParams.put("campaignId", cid);
		mapParams.put("id", id);
		mapParams.put("status", status);

		int i = sqlSessionHandler.update("creativeMapper.update:status", mapParams);

		if (i > 0) {
			logger.info("成功更新订单[{}]下的创意[{}]的状态为[{}]", cid, id, status);
		} else {
			logger.error("更新订单[{}]下的创意[{}]的状态为[{}]操作失败", cid, id, status);
			throw new CreativeValidateException(CreativeValidateException.ErrorCode.CREATIVE_UPDATE_STATUS_FAILURE);
		}
	}

	/**
	 * 快捷编辑创意的状态
	 */
	@Transactional
	public void updateCreativeStatus(Integer cid, Integer id, Integer status) {
		// 查询创意信息
		Creative creative = selectCreativeById(id);
		if (creative == null || !new Integer(cid).equals(creative.getCampaignId())) {
			logger.error("订单[{}]下不存在创意[{}]", cid, id);
			throw new CreativeValidateException(CreativeValidateException.ErrorCode.CREATIVE_NOTFOUND);
		}

		if (new Integer(CreativeStatus.INVALID.getValue()).equals(status)) { // 置为无效
			if (new Integer(CreativeStatus.VALID.getValue()).equals(creative.getStatus())) {
				logger.info("订单[{}]下的创意[{}]的当前状态为[{}], 将要更新为[{}]", cid, id, creative.getStatus(), status);
				updateLocalCreativeStatus(cid, id, status);
			} else {
				logger.info("订单[{}]下的创意[{}]的当前状态为[{}], 不需要更新", cid, id, creative.getStatus());
			}
		} else if (new Integer(CreativeStatus.VALID.getValue()).equals(status)) { // 置为有效
			if (new Integer(CreativeStatus.INVALID.getValue()).equals(creative.getStatus())) {
				logger.info("订单[{}]下的创意[{}]的当前状态为[{}], 将要更新为[{}]", cid, id, creative.getStatus(), status);
				updateLocalCreativeStatus(cid, id, status);
			} else {
				logger.info("订单[{}]下的创意[{}]的当前状态为[{}], 不需要更新", cid, id, creative.getStatus());
			}
		}
	}

	/**
	 * 快捷编辑创意分组下所有创意的状态
	 */
	@Transactional
	public void updateCreativeStatusForCreativeGroup(Integer cid, Integer creativeGroupId, Integer status) {

		// 查询创意分组下的创意列表
		List<Integer> creativeList = findCreativeListByCreativeGroup(cid, creativeGroupId);
		for (Integer creativeId : creativeList) {
			// 更新创意的状态
			updateCreativeStatus(cid, creativeId, status);
		}
	}

	/**
	 * 查询创意分组下或者订单下的创意列表 详细信息
	 */
	public ResultSetList<CreativeDetailModel> findCreativeList(Map<String, Object> searchMap, PageParameter pageInfo) {
		// 获取到创意列表
		List<CreativeDetailModel> creativeList = sqlSessionHandler.selectList("creativeMapper.select:creative:list:page", searchMap, pageInfo);

		for (CreativeDetailModel creativeDetailModel : creativeList) {
			// 查询该创意的素材列表
			selectMaterialList(creativeDetailModel);
		}

		// 封装成BO对象
		return new ResultSetList<>(pageInfo.getTotalCount(), creativeList);
	}

	private void selectMaterialList(CreativeDetailModel creativeDetailModel) {
		// 根据创意形式查询该创意下的所有素材
		if (creativeDetailModel != null) {
            Map<String, Object> params = new HashMap<String, Object>();
            // 设置创意ID
            params.put("creativeId", creativeDetailModel.getId());
            if (creativeDetailModel.getAdFormat() == AdFormat.ADFORMAT_NATIVE.getValue()) {
                // 原生模版素材列表
                List<AdMaterialDetailModel> materials = sqlSessionHandler.selectList("adMaterialGroupMapper.template:material:list", params);
                creativeDetailModel.setMaterials(materials);
            } else {
                // 非原生创意形式 素材列表
                List<AdMaterialDetailModel> materials = sqlSessionHandler.selectList("adMaterialMapper.material:list", params);
                creativeDetailModel.setMaterials(materials);
            }
        }
	}


	// 判断非原生创意 模版元素是否有修改
	private boolean isAdTemplateElementInfoChangeForNativeCreativeForFMOBI(CreativeDetailModel creativeDetailModel,
                                                                           Map<Integer, AdMaterialDetailModel> mapMaterialsFromDB, List<AdMaterialDetailModel> materialsFromParam) {

		// 设置flag标识模版元素是否有修改
		boolean materialInfoChangeFlag = false;

		// (原生创意时不能修改平台和模版，理论上不会存在元素的新增和删除)
		for (AdMaterialDetailModel materialFromParam : materialsFromParam) {

			// 根据原生创意id，模版id，模版规格id 查询素材id
			Integer materialId = findMaterialIdForNativeCreative(creativeDetailModel.getId(), creativeDetailModel.getTemplateId(), materialFromParam.getTemplateSpecId());

			AdMaterialDetailModel materialFromDB = mapMaterialsFromDB.get(materialId);

			// 判断原生模版元素是否有修改
			if (materialFromParam.getMaterialTypeId() == MaterialType.MATERIALTYPE_PICTURE.getValue()) {
				// 如果是图片元素，判断图片是否有修改
				if (!StringUtils.equals(materialFromParam.getMaterialUrl(), materialFromDB.getMaterialUrl())) {
					materialInfoChangeFlag = true;
					break;
				}
			}

			if (materialFromParam.getMaterialTypeId() == MaterialType.MATERIALTYPE_TEXT.getValue()) {
				// 如果是文本元素，判断文本是否有修改
				if (!StringUtils.equals(materialFromParam.getMaterialText(), materialFromDB.getMaterialText())) {
					materialInfoChangeFlag = true;
					break;
				}
			}

			// 只要有一个元素有修改就终止for循环
			if (materialInfoChangeFlag) {
				break;
			}
		}

		return materialInfoChangeFlag;
	}

	// 根据原生创意id，模版id，模版规格id 查询素材id
	private Integer findMaterialIdForNativeCreative(Integer creativeId, Integer templateId, Integer templateSpecId) {
		Map<String, Object> mapParams = new HashMap<>();
		mapParams.put("creativeId", creativeId);
		mapParams.put("templateId", templateId);
		mapParams.put("templateSpecId", templateSpecId);
		return sqlSessionHandler.selectOne("adMaterialGroupMapper.selectMaterialId", mapParams);
	}

	/**
	 * 根据创意id查询创意信息
	 */
	public Creative selectCreativeById(Integer creativeId) {
		return sqlSessionHandler.selectOne("creativeMapper.select:creative:by:id", creativeId);
	}

	/***
	 * 查询创意分组下的创意列表
	 */
	public List<Integer> findCreativeListByCreativeGroup(Integer campaignId, Integer creativeGroupId) {
		Map<String, Object> mapParams = new HashMap<>();
		mapParams.put("id", creativeGroupId);
		mapParams.put("campaignId", campaignId);
		// 根据订单id和创意分组id， 查询该订单下是否存在该创意分组
		CreativeGroup creativeGroupFromDB = sqlSessionHandler.selectOne("creativeGroupMapper.select:by:id:and:campaignId", mapParams);
		if (creativeGroupFromDB == null) {
			logger.error("在订单{}下不存在该创意分组{}", campaignId, creativeGroupId);
			throw new CreativeGroupValidateException(CreativeGroupValidateException.ErrorCode.CREATIVE_GROUP_NOTFOUND);
		}

		return sqlSessionHandler.selectList("creativeMapper.select:all:creative:list:by:creative:group", creativeGroupId);
	}

	/**
	 * 查询创意列表
	 * @param advertiserId
	 * @return
	 */
	public List<CreativeAdvertiserModel> findCreativeList(Integer advertiserId) {
		return sqlSessionHandler.selectList("creativeMapper.creative:advertiser:list", advertiserId);
	}

	public List<DropDownModel> findCreativePlatfromList(Integer creativeId) {
		return sqlSessionHandler.<DropDownModel>selectList("creativeMapper.select:platform:by:creativeId", creativeId);
	}

	// ************************************************************参数验证 START **************************************************************

	/**
	 * 创意基本参数验证
	 *
	 * @param creativeDetailModel
	 *            创意基本信息
	 */
	private void creativeParamValidate(CreativeDetailModel creativeDetailModel) {
		// 订单id是否存在
		campaignService.getCampaignById(creativeDetailModel.getCampaignId());

		// 素材基础信息验证
		if (new Integer(AdFormat.ADFORMAT_NATIVE.getValue()).equals(creativeDetailModel.getAdFormat())) {
			// 原生

			// 平台是否存在
			Platform p = platformService.selectPlatformByIdAndStatus(creativeDetailModel.getPlatformId());
			if (p == null) {
				logger.error("平台[{}]不存在!", creativeDetailModel.getPlatformId());
				throw new CreativeValidateException(CreativeValidateException.ErrorCode.CREATIVE_NATIVE_PLATFORM_NOTFOUND);
			}

			// 模版
			AdTemplateDetailModel adTemplateDetailModel = adTemplateService.selectAdTemplateDetailById(creativeDetailModel.getTemplateId());
			if (adTemplateDetailModel == null || !creativeDetailModel.getPlatformId().equals(adTemplateDetailModel.getPlatformId())) {
				logger.error("原生模版[{}]不存在!", creativeDetailModel.getTemplateId());
				throw new CreativeValidateException(CreativeValidateException.ErrorCode.CREATIVE_NATIVE_ADTEMPLATE_NOTFOUND);
			}

			// interaction_type 为空时，该模版支持所有交互方式
			if (!StringUtils.isEmpty(adTemplateDetailModel.getInteractionType())) {
				if (!isInteractionMatch(creativeDetailModel.getInteractionType(), creativeDetailModel.getAppType(), adTemplateDetailModel.getInteractionType())) {
					logger.error("创意的交互方式为[{}], 原生模版[{}]支持的交互方式为[{}]!", creativeDetailModel.getInteractionType(), creativeDetailModel.getTemplateId(), adTemplateDetailModel.getInteractionType());
					throw new CreativeValidateException(CreativeValidateException.ErrorCode.CREATIVE_TEMPLATE_INTERACTION_TYPE_NOTMATCH);
				}
			}

			// 查询原生模版元素列表
			List<AdTemplateSpecListModel> templateSpecList = adTemplateSpecService.getAdTemplateSpecByTemplatId(creativeDetailModel.getTemplateId());
			if (CollectionUtils.isEmpty(templateSpecList)) {
				logger.error("基础数据异常, 没有查询到原生模版[{}]的元素规格列表", creativeDetailModel.getTemplateId());
				throw new CreativeValidateException(CreativeValidateException.ErrorCode.CREATIVE_TEMPLATE_SPEC_LIST_NOTFOUND);
			}

			Set<String> materialSpecFromDB = new HashSet<>();
			for (AdTemplateSpecListModel templateSpec : templateSpecList) {
				if (null == templateSpec.getId() || 0 == templateSpec.getId()) {
					logger.error("基础数据异常, 查询到的原生模版[{}]的元素规格id异常", creativeDetailModel.getTemplateId());
					throw new CreativeValidateException(CreativeValidateException.ErrorCode.CREATIVE_TEMPLATE_SPEC_LIST_NOTFOUND);
				}

				if (!new Integer(MaterialType.MATERIALTYPE_PICTURE.getValue()).equals(templateSpec.getElementType())
						&& !new Integer(MaterialType.MATERIALTYPE_TEXT.getValue()).equals(templateSpec.getElementType())){
					logger.error("基础数据异常, 查询到的原生模版[{}]下的元素规格[{}]的elementType异常", creativeDetailModel.getTemplateId(), templateSpec.getId());
					throw new CreativeValidateException(CreativeValidateException.ErrorCode.CREATIVE_TEMPLATE_SPEC_LIST_NOTFOUND);
				}

				if (null == templateSpec.getIndex()) {
					logger.error("基础数据异常, 查询到的原生模版[{}]下的元素规格[{}]中的index值异常", creativeDetailModel.getTemplateId(), templateSpec.getId());
					throw new CreativeValidateException(CreativeValidateException.ErrorCode.CREATIVE_TEMPLATE_SPEC_LIST_NOTFOUND);
				}

				// filterType为空时 支持所有
				if (!StringUtils.isEmpty(templateSpec.getFilterType())) {
					if (isInteractionMatch(creativeDetailModel.getInteractionType(), creativeDetailModel.getAppType(), templateSpec.getFilterType())) {
						String key = new StringBuilder(templateSpec.getId()).
								append("_").
								append(templateSpec.getElementType()).toString();

						if(!materialSpecFromDB.contains(key)) {
							materialSpecFromDB.add(key);
						}
					}
				} else {
					String key = new StringBuilder(templateSpec.getId()).
							append("_").
							append(templateSpec.getElementType()).toString();

					if(!materialSpecFromDB.contains(key)) {
						materialSpecFromDB.add(key);
					}
				}
			}

			List<AdMaterialDetailModel> materialList = creativeDetailModel.getMaterials();
			for (AdMaterialDetailModel material : materialList) {
				if(!materialSpecFromDB.contains(new StringBuilder(material.getTemplateSpecId()).
						append("_").append(material.getMaterialTypeId()).toString())) {
					logger.error("模版元素规格参数错误：模版元素规格[{}]模版元素类型[{}]", material.getTemplateSpecId(), material.getMaterialTypeId());
					throw new CreativeValidateException(CreativeValidateException.ErrorCode.CREATIVE_TEMPLATE_SPEC_LIST_NOTFOUND);
				}
			}

		} else if (new Integer(AdFormat.ADFORMAT_BANNER.getValue()).equals(creativeDetailModel.getAdFormat())
				|| new Integer(AdFormat.ADFORMAT_INTERSTITINAL.getValue()).equals(creativeDetailModel.getAdFormat())
				|| new Integer(AdFormat.ADFORMAT_SPREAD.getValue()).equals(creativeDetailModel.getAdFormat())){
			// 非原生
			if (!CollectionUtils.isEmpty(creativeDetailModel.getMaterials())) {
				for (AdMaterialDetailModel adMaterialDetailModel : creativeDetailModel.getMaterials()) {

					// 验证该尺寸是否存在
					AdSize adSize = adSizeService.selectBySizeId(adMaterialDetailModel.getSizeId());
					if (adSize == null) {
						logger.error("素材尺寸[{}]不存在", adMaterialDetailModel.getSizeId());
						throw new CreativeValidateException(CreativeValidateException.ErrorCode.CREATIVE_SIZE_ID_NOTFOUND);
					} else {
						int count = creativeFormatMaterialSpecService.selectCountByFormatIdSizeId(creativeDetailModel.getAdFormat(), adMaterialDetailModel.getSizeId());
						if (count <= 0) {
							logger.error("在广告形式[{}]下不存在素材尺寸[{}]", creativeDetailModel.getAdFormat(), adMaterialDetailModel.getSizeId());
							throw new CreativeValidateException(CreativeValidateException.ErrorCode.CREATIVE_SIZE_ID_NOTFOUND);
						}
					}
				}
			}
		}
	}

	/**
	 * 创意交互方式和模版或者模版元素所支持的交互是否匹配
	 *
	 * @param creativeInteractionType
	 *            创意的交互方式
	 * @param creativeAppType
	 *            创意APP下载的交互类型
	 * @param templateInteraction
	 *            模版或者模版元素支持的的交互类型
	 * @return
	 */
	private boolean isInteractionMatch(Integer creativeInteractionType, Integer creativeAppType, String templateInteraction) {

		boolean flag = true;
		if (!((creativeInteractionType.equals(InteractionType.INTERACTIONTYPE_REDIRECT.getValue())
				&& (templateInteraction.indexOf(Interaction.INTERACTIONTYPE_LINK.getDescription()) >= 0
				|| templateInteraction.indexOf(Interaction.INTERACTIONTYPE_LINK_WECHAT.getDescription()) >= 0))
				|| (creativeInteractionType.equals(InteractionType.INTERACTIONTYPE_APP.getValue())
				&& new Integer(OsType.ANDROID.getValue()).equals(creativeAppType)
				&& templateInteraction.indexOf(Interaction.INTERACTIONTYPE_APP_ANDROID.getDescription()) >= 0)
				|| (creativeInteractionType.equals(InteractionType.INTERACTIONTYPE_APP.getValue())
				&& new Integer(OsType.IOS.getValue()).equals(creativeAppType)
				&& templateInteraction.indexOf(Interaction.INTERACTIONTYPE_APP_IOS.getDescription()) >= 0)))	{
			flag = false;
		}

		return flag;
	}

	// 创意不可修改点验证
	private void validateCreativeInfoChangeWhenEditCreative(CreativeDetailModel creativeDetailModel,
															CreativeDetailModel creativeDetailInfoFromDB) {
		// 编辑创意时创意分组不可修改
		if (null == creativeDetailModel.getCreativeGroupId()) {
			if (null != creativeDetailInfoFromDB.getCreativeGroupId()) {
				throw new CreativeValidateException(CreativeValidateException.ErrorCode.CREATIVE_CREATIVEGROUP_CHANGE);
			}
		} else {
			if (!new Integer(creativeDetailModel.getCreativeGroupId()).equals(creativeDetailInfoFromDB.getCreativeGroupId())) {
				throw new CreativeValidateException(CreativeValidateException.ErrorCode.CREATIVE_CREATIVEGROUP_CHANGE);
			}
		}

		// 编辑创意时，交互方式不可修改
		if (creativeDetailModel.getInteractionType() != creativeDetailInfoFromDB.getInteractionType()) {
			throw new CreativeValidateException(CreativeValidateException.ErrorCode.CREATIVE_INTERACTIONTYPE_CHANGE);
		}

		// 编辑创意时，创意形式不可修改
		if (creativeDetailModel.getAdFormat() != creativeDetailInfoFromDB.getAdFormat()) {
			throw new CreativeValidateException(CreativeValidateException.ErrorCode.CREATIVE_ADFORMAT_CHANGE);
		}

		// 编辑原生创意时，平台 以及模板不可修改
		if (creativeDetailInfoFromDB.getAdFormat() == AdFormat.ADFORMAT_NATIVE.getValue()) {
			if (!creativeDetailModel.getPlatformId().equals(creativeDetailInfoFromDB.getPlatformId())) {
				throw new CreativeValidateException(CreativeValidateException.ErrorCode.CREATIVE_PLATFORM_CHANGE);
			}

			if (!creativeDetailModel.getTemplateId().equals(creativeDetailInfoFromDB.getTemplateId())) {
				throw new CreativeValidateException(CreativeValidateException.ErrorCode.CREATIVE_ADTEMPLATE_CHANGE);
			}
		}
	}

	// ************************************************************参数验证 END**************************************************************

	
	// ************************************************************创意修改点验证 START**************************************************************
	
	// 根据合作方channel ID 判断创意修改点
	private boolean isCreativeInfoChangeForChannel(Integer channelId, CreativeDetailModel creativeDetailModel, CreativeDetailModel creativeDetailInfoFromDB) {
		if (new Integer(Constant.FALCON_CHANNEL_ID).equals(channelId)) {
			return isCreativeInfoChangeForFalcon(creativeDetailModel, creativeDetailInfoFromDB);
		} else if (new Integer(Constant.ADVIEW_CHANNEL_ID).equals(channelId)) {
			return isCreativeInfoChangeForAdView(creativeDetailModel, creativeDetailInfoFromDB);
		} else if (new Integer(Constant.GDT_ADX_CHANNEL_ID).equals(channelId)) {
			return isCreativeInfoChangeForGdtAdx(creativeDetailModel, creativeDetailInfoFromDB);
		} else if (new Integer(Constant.BES_ADX_CHANNEL_ID).equals(channelId)) {
			return isCreativeInfoChangeForBesAdx(creativeDetailModel, creativeDetailInfoFromDB);
		} else {
			return false;
		}
	}

	// 判断创意信息是否有修改
	private boolean isCreativeInteractionInfoChange(CreativeDetailModel creativeDetailModel, CreativeDetailModel creativeDetailInfoFromDB) {
		// 如果创意修改了交互方式或者目标地址或者APP下载地址，其所有素材需要重新审核
		if (creativeDetailModel.getInteractionType() != creativeDetailInfoFromDB.getInteractionType()) {
			return true;
		} else if (creativeDetailModel.getInteractionType() == InteractionType.INTERACTIONTYPE_REDIRECT.getValue()
				&& !StringUtils.equals(creativeDetailModel.getTargetUrl(), creativeDetailInfoFromDB.getTargetUrl())) {
			return true;
		} else if (creativeDetailModel.getInteractionType() == InteractionType.INTERACTIONTYPE_APP.getValue()
				&& !StringUtils.equals(creativeDetailModel.getDownloadUrl(), creativeDetailInfoFromDB.getDownloadUrl())) {
			return true;
		}
		return false;
	}

	// Falcon
	private boolean isCreativeInfoChangeForFalcon(CreativeDetailModel creativeDetailModel, CreativeDetailModel creativeDetailInfoFromDB) {
		return isCreativeInteractionInfoChange(creativeDetailModel, creativeDetailInfoFromDB);
	}

	// AdView
	private boolean isCreativeInfoChangeForAdView(CreativeDetailModel creativeDetailModel, CreativeDetailModel creativeDetailInfoFromDB) {
		return isCreativeInteractionInfoChange(creativeDetailModel, creativeDetailInfoFromDB);
	}

	// GDT_ADX
	private boolean isCreativeInfoChangeForGdtAdx(CreativeDetailModel creativeDetailModel, CreativeDetailModel creativeDetailInfoFromDB) {
		if (creativeDetailModel.getInteractionType() != creativeDetailInfoFromDB.getInteractionType()) {
			return true;
		} else if (creativeDetailModel.getInteractionType() == InteractionType.INTERACTIONTYPE_REDIRECT.getValue()) {
			if (!StringUtils.equals(creativeDetailModel.getTargetUrl(), creativeDetailInfoFromDB.getTargetUrl())) {
				return true;
			}
		} else if (creativeDetailModel.getInteractionType() == InteractionType.INTERACTIONTYPE_APP.getValue()) {
			if (creativeDetailModel.getAppType() != creativeDetailInfoFromDB.getAppType()) {
				if (creativeDetailModel.getAppType() == 2 || creativeDetailModel.getAppType() == 3) {
					return true;
				}
			} else {
				if (creativeDetailModel.getAppType() == 2 || creativeDetailModel.getAppType() == 3) {
					if (!StringUtils.equals(creativeDetailModel.getStoreId(), creativeDetailInfoFromDB.getStoreId())) {
						return true;
					}
				}
			}
		}

		// 展示监测地址前两个是否修改
		if (isCreativeImpressionTrackingUrlChange(creativeDetailModel, creativeDetailInfoFromDB)){
			return true;
		}
		
		return false;
	}

	// 验证展示监测地址前两个是否修改
	private boolean isCreativeImpressionTrackingUrlChange(CreativeDetailModel creativeDetailModel,
			CreativeDetailModel creativeDetailInfoFromDB) {
		if (!DataUtils.isNull(creativeDetailModel.getImpressionTracking()) && !DataUtils.isNull(creativeDetailInfoFromDB.getImpressionTracking())) {
			if(!this.getImpressionTrack(creativeDetailModel.getImpressionTracking()).
					equals(this.getImpressionTrack(creativeDetailInfoFromDB.getImpressionTracking()))) {
				return true;
			}
		} else if (!StringUtils.equals(creativeDetailModel.getImpressionTracking(), creativeDetailInfoFromDB.getImpressionTracking())){
			return true;
		}
		
		return false;
	}
	
	// BES_ADX
	private boolean isCreativeInfoChangeForBesAdx(CreativeDetailModel creativeDetailModel, CreativeDetailModel creativeDetailInfoFromDB) {
		// 目标地址或者app下载地址
		if (isCreativeInteractionInfoChange(creativeDetailModel, creativeDetailInfoFromDB)){
			return true;
		}
		
		// 验证展示监测地址前两个是否修改
		if (isCreativeImpressionTrackingUrlChange(creativeDetailModel,creativeDetailInfoFromDB)) {
			return true;
		}
		
		// APP下载地址
		if (InteractionType.INTERACTIONTYPE_APP.getValue() == creativeDetailModel.getInteractionType()) {
			if (!StringUtils.equals(creativeDetailModel.getAppName(), creativeDetailInfoFromDB.getAppName())) {
				return true;
			}
			
			if (!StringUtils.equals(creativeDetailModel.getAppDesc(), creativeDetailInfoFromDB.getAppDesc())) {
				return true;
			}
			
			if (!this.floatEquals(creativeDetailModel.getAppVolume(), creativeDetailInfoFromDB.getAppVolume())) {
				return true;
			}
		}
		
		return false;
	}

	// Float比较大小
	private boolean doubleEquals(Double a, Double b) {
		if (a == null) {
			return b == null;
		}
		return a.equals(b);
	}
	
	// Float比较大小
    private boolean floatEquals(Float a, Float b) {
        if (a == null) {
            return b == null;
        }
        return a.equals(b);
    }
	 
	/**
	 * 提取前两个监测地址
	 * 
	 * @param str
	 *            要操作的字符串
	 * @return
	 */
	private List<String> getImpressionTrack(String str) {
		List<String> monitorUrls = new ArrayList<>();
		if (!DataUtils.isNull(str)) {
			String sTrack[] = str.split("\\|\\|\\|");
			if (sTrack.length < 2) {
				monitorUrls.add(sTrack[0]);
			} else {
				monitorUrls.add(sTrack[0]);
				monitorUrls.add(sTrack[1]);
			}
		}
		return monitorUrls;
	}
	
}
